package com.tang.chat.ws;

import com.alibaba.fastjson2.JSON;
import com.tang.chat.config.GetHttpSessionConfig;
import com.tang.chat.utils.MessageUtil;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author tmh
 * @date 2024/5/5 16:00
 * @description @ServerEndpoint("/chat")，添加了这个注解表示这个注解可以用于websocket会话
 */
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class)
@Component
public class ChatEndpoint {

    private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();

    private HttpSession httpSession;

    /**
     * 建立webSocket连接之后被调用
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        //1.将session进行保存
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        String user = (String) this.httpSession.getAttribute("user");
        onlineUsers.put(user,session);
        //2.广播消息，需要将登录的所有用户推送给所有的用户
        String message = MessageUtil.getMessage(true, null, getFriends());
        broadCaseAllUser(message);

    }

    private Set<String> getFriends() {
        return onlineUsers.keySet();
    }

    /**
     * 广播消息
     * @param message
     */
    private void broadCaseAllUser(String message){
        //遍历map集合
        for (Map.Entry<String, Session> entry : onlineUsers.entrySet()) {
            //获取到所有用户对应的session
            Session session = entry.getValue();
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                //记录日志
            }
        }

    }

    /**
     * 浏览器发送消息到服务端，该方法会被调用
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {
        //将消息推送给指定的用户
        Message msg = JSON.parseObject(message, Message.class);
        //获取消息接受方的用户名
        String toName = msg.getToName();
        String mess = msg.getMessage();
        //获取消息接收方用户对应的session对象
        Session session = onlineUsers.get(toName);
        String user = (String) this.httpSession.getAttribute("user");
        String msg1 = MessageUtil.getMessage(false, user, mess);
        try {
            session.getBasicRemote().sendText(msg1);
        } catch (IOException e) {
            //记录日志
        }

    }

    /**
     * 断开websocket连接时被调用
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        //1.从onlineUsers中剔除当前用户的session对象
        String user = (String) this.httpSession.getAttribute("user");
        onlineUsers.remove(user);
        //2.通知其他所有用户，当前用户下线了
        String message = MessageUtil.getMessage(true, null, getFriends());
        broadCaseAllUser(message);
    }
}
